package pri.zxx.nio;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.nio.ByteBuffer;

/**
 * @author Twilight
 * @desc nio 学习
 * @createTime 2019-06-29-21:16
 */
@Slf4j
public class BufferTest {

    private static final String testStr = "123sdhnfuinf unfsdkjncpuiowehnrfuiwncsdf";

    @Test
    public void myTest3() {
        //直接缓冲区 在操作系统物理内存中
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);
        //非直接缓冲区 在jvm中缓存
        ByteBuffer bf = ByteBuffer.allocate(1024);
    }

    /**
     * 缓冲区类型
     * <p>
     * ByteBuffer
     * shotBuffer
     * intBuffer
     * FloatBuffer
     * DoubleBuffer
     * ......
     * 基本数据类型除  boolean 无缓冲区
     */
    @Test
    public void bufferTest() {
        /*---------------------- 缓冲区常用操作  -----------------------*/
        //分配一个指定大小的缓冲区 1024
//        ByteBuffer bf = ByteBuffer.allocate(1024);

        ByteBuffer bf = ByteBuffer.allocateDirect(1024);
        int capacity = bf.capacity(); //容量
        int limit = bf.limit();// 可操作性数据大小
        int position = bf.position(); //正在操作的位置
        //position <= limit <=capacity
        log.warn("--------------缓存区属性-----------------");
        log.warn("ca:" + capacity);
        log.warn("limit:" + limit);
        log.warn("position:" + position);

        log.warn("--------------缓存区操作-----------------");
        log.warn("---------put 放入数据 -----------");
        bf.put(testStr.getBytes());
        printInfo(bf);

        log.warn("---------flip 复位-----------");
        bf.flip();//切换模式 更改指向位置
        printInfo(bf);

        log.warn("---------read 读取数据-----------");
        byte[] det = new byte[bf.limit() - 10];
        bf.get(det);//获取数据
        log.warn("读取到的数据:" + new String(det));
        log.warn("缓冲区还有数据吗：{}", bf.hasRemaining());
        log.warn("缓冲区剩余数据：{}", bf.remaining());
        printInfo(bf);

        log.warn("---------rewind 重复读-----------");
        bf.rewind();
        printInfo(bf);

        log.warn("---------clear 清空缓冲区-----------");
        bf.clear();//清空缓冲区（数据处于被遗忘状态） 数据并没有被清空
        printInfo(bf);
    }

    /**
     * 通道类型
     * <p>
     * FileChannel 本地文件通道-本地文件io
     * SocketChannel 套接字通道-网络io
     * ServerSocketChannel 套接字通道-网络io
     * DataGramChannel udp通道-网络io
     * <p>
     * 获取通道方式 getChannel()
     */
    @Test
    public void channelTest() {

    }


    //打印缓冲区信息
    private void printInfo(ByteBuffer bf) {
        log.warn("容量:" + bf.capacity());
        log.warn("最大限制:" + bf.limit());
        log.warn("当前位置:" + bf.position());
    }

}
